
#ifndef LINEARREGRESSION_H
#define	LINEARREGRESSION_H

#include <selforg/matrix.h>

using namespace matrix;
/** 
 * File:   linear_regression.h
 * 
 * Class that implements a linear regression as predictor.
 * The regression coefficients are recurrently updated based on the recursive least squares.
 * As presented in Chapter 3.2.1 of the thesis.
 *
 * 
 * @author:  Athanasios Polydoros
 * @version: 1.0
 * Created on 03 July 2013, 20:35
 */

class LinearRegression {
public:
    /**
     * Class constructor that initialise the members of class. Has to be called
     * in the controller's init method.
     * 
     * @param num_Sensors The number of robot sensors, used as network's outputs
     * @param num_Motors  The number of motors, used as inputs
     */
    LinearRegression(int numSensors, int numMotors);
    
    /**
     * Class destructor
     */
    virtual ~LinearRegression();
     /**
     * Sets the desired output. This method is called within 
     * controler's method : learn() before the method @see predict()
     * 
     * @param sensor the robot's desired sensory values 
     */
    void setDesiredOut(Matrix sensors);
    
     /**
     * Set the current inputs.
     * 
      * This method is called within 
     * controler's method : learn() before the method @see predict()
      * 
     * @param motors The values of robot's motors   
     */
    void setState(Matrix motors);
    
    /**
    *  Predicts the future sensor values based on the current motor commands (inputs).
     * 
     * 
     * @return Matrix that contains the predicted sensory values. 
    */
    Matrix predict();
    
    /**
      * Calculate the jacobian matrix.
      * In the case of regression, it is simply the matrix of regression coefficients
     * without the bias weight.
      * 
      * @param the input nodes values 
      * @return MxM Jacobian matrix
      */
    Matrix getModelMatrix ( Matrix inputs);
    
private:
     /**
     *Update weights based on recursive least square learning rule.
     * 
     */ 
    void updateWeights();
    
    int inputNum;            /**<The number of inputs*/
    int outputNum;           /**<The number of outpouts (targets)*/
    double forgettFactor;    /**<forgeting factor, set to 1, no forgetting*/
    Matrix predictedOut;     /**<The predicted values of outputs */
    Matrix invCorrelation;   /**<The inverse of inputs corellation, used in recursive lest square formula*/
    Matrix inputs;           /**<The values of the inuts*/
    Matrix regression_coeff; /**<The regression coefficients*/
    Matrix desiredOut;       /**<The desired values of the output nodes*/
    Matrix error;            /**<The prediction error*/

};
#endif	/* LINEAR_REGRESSION_H */

